<?php
require_once(CLASS_PATH."Recorder.class.php");
require_once(CLASS_PATH."URL.class.php");
require_once(CLASS_PATH."javaComm.class.php");
require_once (CLASS_PATH . "MacAddr.class.php");
require_once (ROOT."comm/config.php");

class eSign{
  const VERSION = "1.0";
	private $ITSM_GETAPIINFO_URL = ITSM_GETAPIINFO_URL;
	private $TECH_SERVICE_PORT = "8081";
	private $project_id;
	private $project_secret;
	private $token;
	private $devId;
		
  protected $recorder;
  public $urlUtils;
  protected $error;
  protected $javaComm;

  function __construct(){
  	$this->recorder = new Recorder();
  	$this->urlUtils = new URL();
  	$this->javaComm = new javaComm($this->TECH_SERVICE_PORT);
		$this->macAddr = new GetMacAddr(PHP_OS);
		$this->recorder->write( 'equipId', $this->macAddr->mac_addr );
	
		//-------生成唯一随机串防CSRF攻击
    $state = md5(uniqid(rand(), TRUE));
    $this->recorder->write('state',$state);
  }
	
	public function init($project_id, $project_secret)
	{
		if(!empty($this->project_id) && !empty($this->project_secret) 
				&& 0 == strcmp($this->project_id, $project_id) 
				&& 0 == strcmp($this->project_secret, $project_secret))
		{
			return 0;
		}
		$this->project_id = $project_id;
		$this->project_secret = $project_secret;		
		$ret = $this->javaComm->init($project_id, $project_secret);
		return $this->getUrlListFromSrv();
	}
    
  private function getUrlListFromSrv()
  {
  	//-------请求参数列表
    $keysArr = array(
    	"project_id" => $this->project_id,
      "project_secret" => $this->project_secret,
      "channel" => "phptechsdk1.0",
      "version" => "1.0"
    );
		$response = $this->urlUtils->post($this->ITSM_GETAPIINFO_URL, $keysArr);
    //--------检测错误是否发生
    $itsm = json_decode($response);

    if($itsm->errCode != 0){
        echo "eSign init error <br>" . $itsm->errCode;
        return (int)$itsm->errCode;
    }
    $this->saveUrlInfo($itsm->urls);
    return 0;
  }
  
  private function saveUrlInfo($urlAry)
	{
		$urlCount = count($urlAry);
		for($i = 0; $i < $urlCount; $i++)
		{
			$url = $urlAry[$i];
			
			if(0 == strcmp($url->urlKey, 'loginUrl'))
			{
				$this->recorder->write('loginUrl', $url->urlValue);
			}
			if(0 == strcmp($url->urlKey, 'techAddAccountUrl'))
			{
				$this->recorder->write('techAddAccountUrl', $url->urlValue);
			}
			if(0 == strcmp($url->urlKey, 'techAddTempSealUrl'))
			{
				$this->recorder->write('techAddTempSealUrl', $url->urlValue);
			}
			if(0 == strcmp($url->urlKey, 'techSignHashUrl'))
			{
				$this->recorder->write('techSignHashUrl', $url->urlValue);
			}
			if(0 == strcmp($url->urlKey, 'techSaveSignlogUrl'))
			{
				$this->recorder->write('techSaveSignlogUrl', $url->urlValue);
			}
			if(0 == strcmp($url->urlKey, 'techSaveSignedFile'))
			{
				$this->recorder->write('techSaveSignedFile', $url->urlValue);
			}
			if(0 == strcmp($url->urlKey, 'techGetDocUrlUrl'))
			{
				$this->recorder->write('techGetDocUrlUrl', $url->urlValue);
			}
			if(0 == strcmp($url->urlKey, 'ConvertDocUrl'))
			{
				$this->recorder->write('ConvertDocUrl', $url->urlValue);
			}	
		}
	}
        
	public function projectid_login(){
		$equipId = $this->recorder->read("equipId");
    //-------构造请求参数列表
    $keysArr = array(
  		"project_id" => $this->project_id,
  		"project_secret" => $this->project_secret,			
  		"response_type" => "post",
  		"equipId" => $equipId,
  		"loginType" => "4",
		);
    $login_url = $this->urlUtils->post($this->recorder->read('loginUrl'), $keysArr);
		// //写入登陆日志
		// if(!file_exists(LOG_ROOT_PATH . 'temp/') && !is_dir(LOG_ROOT_PATH . 'temp/'))
		// {
		// 	mkdir(LOG_ROOT_PATH . 'temp/'); 
		// }
		// $myfile = fopen(LOG_ROOT_PATH . 'temp/' . "vipfile_" . date('Y-m-d') . ".log","a+");
		// fwrite($myfile, date('Y-m-d H:i:s') . ' projectid_login URL:' . $this->recorder->read('loginUrl') . '. 参数:' . json_encode($keysArr) . '返回值:' . $login_url . " \r\n ");
		// fclose($myfile);
		// echo '<br>==============';
		// print_r($login_url);
		// echo '<br>==============';
		$ret_json = json_decode($login_url,TRUE);
		$errCode = $ret_json['errCode'];
		if($errCode == 0)
		{
			$this->token = $ret_json['token'];			
			//$this->recorder->write('token',$this->token);
			$this->devId = $ret_json['accountId'];			
			//echo '登录成功：token--' . $this->token . '<br>';
			$this->javaComm->projectid_login();
			return true;
		}
		return false;		
  }	
	public function addPersonAccount($mobile, $name, $idNo,$personarea=0, $email='', $organ='', $title='', $address='')
  //public function addPersonAccount($mobile, $name, $idNo, $email='', $organ='', $title='', $address='')
	{
		$personareaArr=array(0=>"0",1=>"1",2=>"2",3=>"3",4=>"4");
		if(($personarea!="0"&&empty($personarea))||!in_array($personarea, $personareaArr))
		{
			//return $this->showError('用户或企业法人归属地非法');
			return array(
					errCode => 1000,
					msg => "用户或企业法人归属地非法",
					errShow => false);
		}
		$keysArr = array(
  		"token" => $this->token,
  		"equipId" => $this->recorder->read("equipId"),
			"account"=>array(
				"email"=>$email,	//邮箱地址
				"mobile" => $mobile,	//手机号码
				"person" => array
				(
				  "name" => $name,		//真实姓名
				  "idNo" => $idNo,		//身份证号码
				  "organ" => $organ,			//公司
				  "title" => $title,		//职务
				  "address" => $address,	//邮寄地址
				  "personArea"=>$personarea //用户归属地
				)
			)
		);
        list($return_code, $return_content) = $this->urlUtils->http_post_json($this->recorder->read('techAddAccountUrl'), json_encode($keysArr));
		if($return_code != 200)
		{
			return array(
					errCode => 101,
					msg => "网络错误",
					httpError=>$return_code,
					httpRet =>$return_content,
					errShow => false);
		} 
		return json_decode($return_content,TRUE);
  }
 
	/*
	 *	@todo 创建企业账号
	 *	@param	mobile 手机号码（不可空）
	 *			name 机构名称（不可空）
	 *			organCode 组织机构代码号（不可空）
	 *			email 邮箱地址（可空）
	 *			organType 单位类型，0-普通企业，1-社会团体，2-事业单位，3-民办非企业单位，4-党政及国家机构，默认0（可空）
	 *			regCode 工商注册号（可空）
	 *			legalName 法定代表姓名，当注册类型为2时必填（可空）
	 *			legalArea 法定代表人归属地,0-大陆，1-香港，2-澳门，3-台湾，4-外籍（不可控）
	 *			userType 注册类型，1-代理人注册，2-法人注册，默认1（可空）
	 *			agentName 代理人姓名，当注册类型为1时必填
	 *			agentIdNo 代理人身份证号，当注册类型为1时必填
	 *			legalIdNo 法定代表身份证号/护照号，当注册类型为2时必填
	*/
	public function addOrganizeAccount($mobile, $name, $organCode, $legalArea=0, $usertype='1', $agentName,$agentIdNo,$legalIdNo, $legalName, $organType=0, $email='', $regCode ='')
	{
		$personareaArr=array(0=>"0",1=>"1",2=>"2",3=>"3",4=>"4");
		if(($legalArea!="0"&&empty($legalArea))||!in_array($legalArea, $personareaArr,true))
		{
			//return $this->showError('用户或企业法人归属地非法');
			return array(
					errCode => 1000,
					msg => "用户或企业法人归属地非法",
					errShow => false);
		}
		switch ($usertype) {
			case '1':
				if(empty($agentName)||empty($agentIdNo)){
					//return $this->showError('代理注册时，代理人姓名和身份证号不能为空!');
					return array(
					errCode => 1001,
					msg => "代理注册时，代理人姓名和身份证号不能为空",
					errShow => false);
				}
				break;
			case '2':
				if(empty($legalName)||empty($legalIdNo)){
					//return $this->showError('法人注册时，法人姓名和身份证号不能为空!');
					return array(
					errCode => 1003,
					msg => "法人注册时，法人姓名和身份证号不能为空",
					errShow => false);
				}
				break;
			
			default:
				//return $this->showError('注册类型不合法!');
				return array(
					errCode => 1004,
					msg => "注册类型不合法",
					errShow => false);
				break;
		}
		//$regType 营业执照类型 0-普通营业执照（机构号码9位） 1-三合一营业执照（机构号码18位），默认为0
		$regType = 0;
		if (strlen($organCode) == 18)
		{
			$regType = 1;
		}
		$keysArr = array(
  		"token" => $this->token,
  		"equipId" => $this->recorder->read("equipId"),
			"account"=>array(
				"email"=>$email,	
				"mobile" => $mobile,
				"organize" => array
				(
				  "name" => $name,		
				  "organCode" => $organCode,		
				  "organType" => $organType,			
				  "regCode" => $regCode,		
				  "legalName" => $legalName,
				  "userType" => $usertype,
				  "legalArea"=>$legalArea, //用户归属地
				  "agentName"=>$agentName, //代理人姓名
				  "agentIdNo"=>$agentIdNo, //代理人身份证号
				  "legalIdNo"=>$legalIdNo, //法人身份证号
				  "licenseType" => $regType
				)
			)
		);
		list($return_code, $return_content) = $this->urlUtils->http_post_json($this->recorder->read('techAddAccountUrl'), json_encode($keysArr));  
		if($return_code != 200)
		{
			return array(
					errCode => 101,
					msg => "网络错误",
					httpError=>$return_code,
					httpRet =>$return_content,
					errShow => false);
		}
		return json_decode($return_content,TRUE);

	}
  
	public function addTemplateSeal($accountId, $templateType='square', $color=1, $hText='', $qText='')
	{
		$keysArr = array(
			"token" => $this->token,
			"equipId" => $this->recorder->read("equipId"),
				"accountId" => $accountId,
				"templateType" => $templateType,
				"color" => $color,
				"hText" => $hText,
				"qText" => $qText
			);
		list($return_code, $return_content) = $this->urlUtils->http_post_json($this->recorder->read('techAddTempSealUrl'), json_encode($keysArr));  
		if($return_code != 200)
		{
			return array(
					errCode => 101,
					msg => "网络错误",
					httpError=>$return_code,
					httpRet =>$return_content,
					errShow => false);
		}
		return json_decode($return_content,TRUE);
	}	
       
	public function signDataHash($data,$accountId = ''){
    $redirect_url = $this->recorder->read("redirect_url");

		if(empty($accountId))
		{
			$accountId = $this->devId;
		}
		
    $hash = base64_encode(hash('sha256',$data,true));
    $keysArr = array(
			"token" => $this->token,
  		"equipId" => $this->recorder->read("equipId"),
			"accountId" => $accountId,
			"hash"=>$hash,
		);

		list($return_code, $return_content) =  $this->urlUtils->http_post_json($this->recorder->read('techSignHashUrl'), json_encode($keysArr));

		$ret = json_decode($return_content,TRUE);
		$errCode = $ret['errCode'];

		if($return_code == 200 && $errCode == 0)
		{
			$signInfo = $ret['signResult'];
			//echo "--------------------signResult :" . $signInfo;
			
			$saveRet = $this->save_hash_tech($hash,$signInfo,$accountId);
			if(is_bool($saveRet) && $saveRet)
			{
				return $signInfo;
			}
			if(is_array($saveRet))
			{
				return $saveRet;
			}
			return array(
				errCode => 1002,
				msg => "保存摘要信息失败",
				errShow => true,
			);
		}
		if(strlen($ret) < 1)
		{
			return array(errCode => 1002,
				msg => "保存摘要信息失败",
				httpError=>$return_code,
				errShow => true,);
		}
		return $ret;
  }
  
	private function save_hash_tech($hash,$signInfo,$accountId='')
	{
		$redirect_url = $this->recorder->read("redirect_url");

		if(empty($accountId))
		{
			$accountId = $this->devId;
		}
		$keysArr = array(
		"token" => $this->token,
		"equipId" => $this->recorder->read("equipId"),
			"accountId" => $accountId,
			"docName" => '',
			"docHash" => $hash,
			"signInfo" => $signInfo,
			"timestamp" => "",
		);

		list($return_code, $return_content) =  $this->urlUtils->http_post_json($this->recorder->read('techSaveSignlogUrl'), json_encode($keysArr));

		$ret = json_decode($return_content,TRUE);
		$errCode = $ret['errCode'];
		if($return_code == 200 && $errCode == 0)
		{
			//echo "--------------------signId: " . $ret['signId'];
			return TRUE;
		}
		return array(
				errCode => 1003,
				msg => "保存摘要信息失败",
				httpError=>$return_code,
				httpRet =>$return_content,
				errShow => false);
	}
  
	public function selfSignPDF($srcPdfFile, $dstPdfFile, $seaId, $signType, $posPage, $posX, $posY, $key, $fileName)
	{  	
		return $this->javaComm->selfSignPDF($this->devId, $srcPdfFile, $dstPdfFile, $seaId, $signType, $posPage, $posX, $posY, $key, $fileName);				
	}
  
	public function selfSignPDFStream($srcPdfFile, $dstPdfFile, $seaId, $signType, $posPage, $posX, $posY, $key, $fileName)
	{ 
		$ret = $this->javaComm->selfSignPDFStream($this->devId, $srcPdfFile, $seaId, $signType, $posPage, $posX, $posY, $key, $fileName);			

		if($ret['errCode'] == 0){
			$saveFile = file_put_contents($dstPdfFile, base64_decode($ret['stream']), true);
		}
		return $ret;
	}
  
	public function userSignPDF($accountId, $sealData, $srcPdfFile, $dstPdfFile, $signType, $posPage, $posX, $posY, $key, $fileName)
	{
		return $this->javaComm->userSignPDF($this->devId, $accountId, $sealData, $srcPdfFile, $dstPdfFile, $signType, $posPage, $posX, $posY, $key, $fileName);				
	}
  
	public function userSignPDFStream($accountId, $sealData, $srcPdfFile, $dstPdfFile, $signType, $posPage, $posX, $posY, $key, $fileName)
	{
		$ret = $this->javaComm->userSignPDFStream($this->devId, $accountId, $sealData, $srcPdfFile, $signType, $posPage, $posX, $posY, $key, $fileName);		  			
		if($ret['errCode'] == 0){
			$saveFile = file_put_contents($dstPdfFile, base64_decode($ret['stream']), true);
		}
		return $ret;
	}
    
	public function saveSignedFile ($docFilePath, $docName, $signer)
	{
		$keysArr = array(
  		"token" => $this->token,
  		"equipId" => $this->recorder->read("equipId"),
			"docName" => $docName,
			"signer" => $signer,
			"file"=> '@'.$docFilePath
		);
		print_r($keysArr);
		echo "<br>";
		echo $this->recorder->read('techSaveSignedFile');
		echo "<br>";
  	$response = $this->urlUtils->post($this->recorder->read('techSaveSignedFile'), $keysArr);
  	if(empty($response))
  	{
  		return array(
				errCode => 101,
				msg => "网络错误",
				httpRet =>$response,
				errShow => false);
  	}
  	return json_decode($response,TRUE);
	}
	
	public function getSignedFile ($docId)
	{
		$keysArr = array(
  		"token" => $this->token,
  		"equipId" => $this->recorder->read("equipId"),
			"docId" => $docId
		);
  	list($return_code, $return_content) = $this->urlUtils->http_post_json($this->recorder->read('techGetDocUrlUrl'), json_encode($keysArr));  
  	if($return_code != 200)
  	{
  		return array(
				errCode => 101,
				msg => "网络错误",
				httpError=>$return_code,
				httpRet =>$return_content,
				errShow => false);
  	}
  	return json_decode($return_content,TRUE);
	}
	
	public function showSealImage($sealData)
	{		
		if(!is_array($sealData))
		{
			$sealData = json_decode($sealData,TRUE);
		}
		if(is_array($sealData))
		{
			// 获取电子印章数据
			$data = base64_decode($sealData['data']);
			$xml = simplexml_load_string($data);
			if(!is_null($xml)){
				return (string)$xml->SealInfo->PictrueInfo->data;
			}
		}
		return '';
	}
	
	public function conv2pdf($docFilePath, $docType)
	{
		$keysArr = array(
			"token" => $this->token,
			"equipId" => $this->recorder->read("equipId"),
			"file" => '@'.$docFilePath,
			"doctype" => $docType
		);

		$response = $this->urlUtils->post($this->recorder->read('ConvertDocUrl'), $keysArr);		
			if(empty($response))
			{
				return array(
						errCode => 101,
						msg => "网络错误",
						httpRet =>$response,
						errShow => false);
			}
		return json_decode($response,TRUE);
	}
}
